home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / tvx.arc / TVX-2.C < prev    next >
C/C++ Source or Header  |  1989-07-30  |  35KB  |  1,437 lines

  1. /* -------------------------------- tvx_2.c ------------------------------- */
  2. /* ========================================================================
  3.  
  4.     tvx_2.c - Part 2 of main TVX code 
  5.  
  6. ============================================================================ */
  7.  
  8. #include "tvx_defs.ic"        /* note tv_defs will #include stdio.h */
  9. #include "tvx_glbl.ic"
  10.  
  11. /* =============================>>> KILLIN <<<============================= */
  12.   killin(cnt)
  13.   int cnt;
  14.   { /* ##  killin - kill cnt lines */
  15.  
  16.     SLOW int i,lim;
  17.     SLOW int from,to,ityp,istrt;
  18.  
  19.     if (cnt+curlin >= nxtlin || (curlin == nxtlin-1 && cnt >= 0))
  20.       {             /* special case: deleting rest of buffer */
  21.     svklin(nxtlin-1);
  22.     for (i = curlin ; i <= nxtlin-1 ; )
  23.         kline(*(lines+i++));
  24.     nxtlin = curlin--;
  25.     if (curlin > 0)
  26.       {
  27.         curchr = *(lines+curlin)+1;
  28.         newscr();
  29.       }
  30.     else
  31.       {
  32.         curchr=0;
  33.         tvclr();
  34.       }
  35.     return;
  36.       }
  37.  
  38.     if (cnt < 0)        /* negative kill */
  39.       {
  40.     cnt = min(-cnt,curlin-1);    /* all upwards? */
  41.     dwnlin(-cnt);        /* go up that far */
  42.       }
  43.  
  44.     if (cnt != 0)
  45.       {
  46.     range(cnt,&to,&from);    /* calculate the line numbers to kill */
  47.  
  48.     curlin=to;        /* remember new current line */
  49.  
  50.     svklin(from);    /* save one line */
  51.     for (i = to ; i <= from ; )        /* mark lines deleted */
  52.         kline(*(lines+i++));
  53.  
  54.     lim = min(nxtlin-1,mxline);
  55.     for (++from ; from <= lim ; )
  56.       {
  57.         *(lines+to++) = *(lines+from++);    /* copy next line number */
  58.       }
  59.  
  60.     nxtlin=to;
  61.     if (nxtlin == curlin)
  62.         --curlin;        /* don't go past end */
  63.     curchr = *(lines+curlin)+1;    /* remember new current character */
  64.  
  65.     if (cnt >= 0 && curlin+(tvlins-tvdlin) < nxtlin &&
  66.       tvdlin < tvlins)    /* killing down */
  67.       {
  68.         tvxy(1,tvy);    /* get to start of line */
  69.         ityp=min(tvlins-tvdlin+1,nxtlin-curlin);
  70.         if (cnt!=1 || !ckline[0])
  71.           {
  72.         tvescr();    /* erase the screen */
  73.         istrt=curlin;
  74.           }
  75.         else
  76.           {
  77.         sendcs(ckline);
  78.         istrt=curlin+ityp-1;
  79.         tvxy(1,tvlins);
  80.         ityp=1;
  81.           }
  82.         tvtype(istrt,ityp);
  83.         tvhdln();    /* home to display line */
  84.       }
  85.     else if ( cnt != 1)    /* neg and > 1 too complicated */
  86.         newscr();            /* kill up, just retype whole screen */
  87.     else if (nxtlin < tvlins)    /* top part of screen */
  88.       {
  89.         if (*ckline)        /* kill line defined */
  90.           {
  91.         tvxy(1,tvy);        /* get to start of line */
  92.         sendcs(ckline);        /* just need to kill the line */
  93.         tvhdln();
  94.           }
  95.         else
  96.         newscr();        /* rewrite it all */
  97.       }
  98.     else if (tvdlin < tvlins)    /* must be in last part of buffer */
  99.       {
  100.         if (*ckline && *ctopb)    /* kill line & topb defined */
  101.           {
  102.         tvxy(1,tvy);        /* get to start of line */
  103.         sendcs(ckline);        /* kill the line */
  104.         if (curlin-tvdlin > 0)    /* something to scroll */
  105.           {
  106.             tvtopb(1);        /* scroll down one line */
  107.             tvtype(curlin-tvdlin,1);    /* type the offscreen line */
  108.             tvdlin++;        /* will start display on next line */
  109.           }
  110.         tvhdln();
  111.           }
  112.         else
  113.         newscr();        /* rewrite it all */
  114.       }
  115.     else        /* if all else fails */
  116.         newscr();
  117.       }
  118.   }
  119.  
  120. /* =============================>>> KLINE  <<<============================= */
  121.   kline(ptr)
  122.   BUFFINDEX ptr;
  123.   {  /* kline - kill off the line beginning at buff position ptr */
  124.  
  125.     SLOW BUFFINDEX i;
  126.  
  127.     for (i=ptr; *(buff+i) != ENDLINE ; )    /* insert GARBAGE to kill */
  128.     *(buff+i++)=GARBAGE;
  129.  
  130.     *(buff+i)=GARBAGE;        /* kill the endline */
  131.   }
  132.  
  133. /* =============================>>> KPREV  <<<============================= */
  134.   kprev()
  135.   { /* kprev - kill from cursor to beginning of line */
  136.  
  137.     FAST int chrs;
  138.  
  139.     svklin(curlin);                /* save one line */
  140.     chrs = curchr - *(lines+curlin) - 1;    /* how much to delete */
  141.     if (chrs > 0)
  142.     delnxt(-chrs);    /* won't cause a combine, so don't worry */
  143.   }
  144.  
  145. /* =============================>>> KREST  <<<============================= */
  146.   krest()
  147.   { /* krest - kill the rest of the line, not including cursor and ENDLINE */
  148.  
  149.     SLOW int chrs;
  150.     SLOW BUFFINDEX i;
  151.  
  152.     svklin(curlin);    /* save one line */
  153.     chrs=0;
  154.     for (i=curchr; *(buff+i)!=ENDLINE; ++i)
  155.     ++chrs;     /* count how much to delete */
  156.     if (chrs > 0)
  157.     delnxt(chrs);    /* won't cause combine, so don't worry */
  158.   }
  159.  
  160. /* =============================>>> NEATEN <<<============================= */
  161.   int neaten(count)
  162.   int count;
  163.   {  /* neaten - fill lines to current margin */
  164.  
  165.     SLOW int oldef, i;
  166.     SLOW BUFFINDEX linbeg;
  167.     SLOW int retval;
  168.  
  169.     retval = TRUE;
  170.     oldef = echof;
  171.     if (count > 1)
  172.     echof = FALSE;
  173.     if (wraplm <= 1 || curlin >= nxtlin-1)
  174.     goto l900;        /* work only if wrap limit turned on */
  175.  
  176.     for (i=1 ; i<=count ; ++i)
  177.       {
  178.     beglin();        /* start at beginning of line */
  179.     if (curlin >= nxtlin-1)
  180.         goto l900;
  181.  
  182.     /* don't neaten leading space, cr, period or tab */
  183.  
  184.     if (*(buff+curchr) == '.')
  185.       {
  186.         dwnlin(1);
  187.         continue;        /* skip dot commands */
  188.       }
  189.  
  190.     while (*(buff+curchr)== ' ' || *(buff+curchr)==ENDLINE
  191.       || *(buff+curchr) == 9)
  192.       {
  193.         right(1);    /* skip this line */
  194.       }
  195.  
  196.     do
  197.       {
  198.         if (*(buff+curchr) == ENDLINE)
  199.           {
  200.         if (tvx+leftmg < wraplm)    /* combine lines! */
  201.           {
  202.             linbeg = *(lines+curlin+1)+1;
  203.             /* pt to first char of next line */
  204.             if (*(buff+linbeg) == ' ' || *(buff+linbeg) == ENDLINE
  205.               || *(buff+linbeg) == 9 || *(buff+linbeg) == '.')
  206.               {
  207.             dwnlin(1);
  208.             break;    /* no more combining */
  209.               }
  210.             if (! neat1(1,32))
  211.             goto l990;
  212.             goto NEATNEXT;    /* tab over another word */
  213.           }
  214.         else
  215.           {
  216.             dwnlin(1);    /* no more combining on line */
  217.             break;
  218.           }
  219.           }
  220.  
  221. NEATNEXT:
  222.         if (*(buff+curchr-1)==' ' && tvx+leftmg >= wraplm)    /* change to cr */
  223.           {
  224.         if (! neat1(-1,CR))    /* delete the blank */
  225.             goto l990;
  226.         break;
  227.           }
  228.         wordr(1);
  229.       } /*# end of the repeat */
  230.     while (1);
  231.       } /*# end of the for     */
  232. l900:
  233.     echof = oldef;
  234.     if (oldef && count > 1)
  235.     newscr();
  236.     return (retval);
  237.  
  238. l990:                /* failure return */
  239.     retval = FALSE;
  240.     goto l900;
  241.   }
  242.  
  243. /* =============================>>> NEAT1  <<<============================= */
  244.   neat1(dir, val)
  245.   int dir, val;
  246.   {  /* change character dir to val */
  247.  
  248.     SLOW int oldwrp;
  249.  
  250.     oldwrp = wraplm;
  251.     wraplm = 0;
  252.     if (! delnxt(dir))
  253.     goto l900;
  254.     if (! ins_chr(val))
  255.     goto l900;
  256.     wraplm = oldwrp;
  257.     return (TRUE);
  258. l900:
  259.     wraplm = oldwrp;
  260.     return (FALSE);
  261.   }
  262.  
  263. /* =============================>>> NEWSCR <<<============================= */
  264.   newscr()
  265.   { /* newscr - retype entire screen, updating cursor position if necessary */
  266.  
  267.    SLOW int ibeg,cnt;
  268.  
  269.     if (tvlins != tvhardlines || nxtlin-1 <= tvlins)
  270.     /* two kinds of screen rewrite */
  271.     tvclr();            /* clear the screen and home */
  272.     else
  273.     tvxy(1,1);
  274.  
  275.     finddl(&ibeg,&cnt);     /* calculate where it will go */
  276.     tvtype(ibeg,cnt);        /* type it out */
  277.     tvhdln();            /* home to display line */
  278.   }
  279.  
  280. /* =============================>>> OPENLN <<<============================= */
  281.   openln(cnt)
  282.   int cnt;
  283.   {  /* openln - open a new line */
  284.  
  285.     FAST int i;
  286.     SLOW int pcnt, oldauto;
  287.  
  288.     oldauto = autoin; autoin = FALSE;    /* don't allow autoindent */
  289.     pcnt = cnt >= 0 ? cnt : (-cnt);    /* only allow positive opens */
  290.     for (i=1; i<=pcnt; ++i)
  291.     ins_chr(CR);    /* insert right number of newlines */
  292.     dwnlin(-pcnt);    /* and goto beginning of the opened line */
  293.     endlin();
  294.     autoin = oldauto;
  295.   }
  296.  
  297. /* =============================>>> RANGE  <<<============================= */
  298.   range(cnt,lbeg,lend)
  299.   int cnt,*lbeg,*lend;
  300.   { /* determine a legal line number range given cnt */
  301.  
  302.     if (cnt <= 0)
  303.       {
  304.     *lbeg=max(curlin+cnt,1);
  305.     *lend=curlin;
  306.     if (cnt < 0)
  307.        *lend = (*lend)-1;
  308.       }
  309.     else
  310.       {
  311.     *lbeg=curlin;
  312.     *lend=min(nxtlin-1,curlin+cnt-1);
  313.       }
  314.  }
  315.  
  316. /* =============================>>> RIGHT  <<<============================= */
  317.   right(cnt)
  318.   int cnt;
  319.   {  /* move cursor right cnt characters
  320.     newlines count as one character */
  321.  
  322.     FAST int change,i;
  323.  
  324.     change=0;            /* nochange yet */
  325.     if (cnt > 0)
  326.       {
  327.     for (i = 1 ; i <= cnt ; ++i)
  328.       {
  329.         if (*(buff+curchr)==ENDLINE)
  330.           {
  331.         if (curlin+1 >= nxtlin)
  332.             break;        /* don't go beyond end! */
  333.         ++curlin;
  334.         ++change;        /* we've gone down one line */
  335.         curchr = *(lines+curlin)+1;
  336.           }
  337.         else
  338.         ++curchr;
  339.       }
  340.       }
  341.     else if (cnt < 0)
  342.       {
  343.     cnt=(-cnt);
  344.     for (i = 1 ; i <= cnt ; ++i)
  345.       {
  346.         --curchr;
  347.         if (*(buff+curchr) == BEGLINE)
  348.           {
  349.         if (curlin > 1)
  350.           {
  351.             --curlin;
  352.             --change;
  353.             for (curchr = *(lines+curlin) ; *(buff+curchr)!=ENDLINE ;
  354.               ++curchr)
  355.             ;    /* bump curchr to end of the line */
  356.           }
  357.         else
  358.           {
  359.             ++curchr;
  360.             break;
  361.           }
  362.           }
  363.       }
  364.       }
  365.     if (change != 0)        /* don't do unnecessary change */
  366.     update(change);
  367.     tvhdln();
  368.   }
  369.  
  370. /* =============================>>> RMVLST <<<============================= */
  371.   int rmvlst()
  372.   {  /* rmvlst - delete the previous thing found or manipulated
  373.     length of oldlen is set by insert, find, and save
  374.     may also use savlen if set by save */
  375.  
  376.     SLOW int oldech;
  377.     static int rmv_set[] =
  378.       {
  379.     VSEARCH, VNEXT, VSAVE, VGET, VSAGAIN, VSAPPEND, VSAPPEND,
  380.     VMVWORD, VMVBWORD, 0
  381.       };
  382.  
  383.     if (!inset(oldlex,rmv_set))
  384.     return (FALSE);
  385.  
  386.     if (savlen > 0)
  387.       {
  388.     if (curlin == nxtlin-1 && slastl != 0)
  389.       {
  390.         --savlen;    /* reduce the count */
  391.         if (savlen > 0)
  392.           {
  393.         oldech = echof;
  394.         echof = FALSE;
  395.         killin(-savlen);    /* kill off previous lines */
  396.         echof = oldech;
  397.           }
  398.         killin(1);        /* kill the last line */
  399.       }
  400.     else
  401.         killin(-savlen);    /* kill off savlen lines */
  402.       }
  403.     else if (oldlen != 0)
  404.       {
  405.     if (! delnxt(-oldlen))
  406.         return (FALSE);
  407.       }
  408.     oldlen = 0;            /* don't allow multiple deletes! */
  409.     savlen = (-1);
  410.     return (TRUE);
  411.   }
  412.  
  413. /* =============================>>> SAVE   <<<============================= */
  414.   int save(cnt,app)
  415.   int cnt,app;
  416.   { /* save - save cnt lines in save buffer */
  417.  
  418.     SLOW int l,lend;
  419.     SLOW BUFFINDEX from;
  420.  
  421.     if (curlin == nxtlin-1 && slastl!=0)
  422.       {
  423.     tverrb("Can't save last line twice! ");
  424.     return (FALSE);
  425.       }
  426.     if (cnt < 0)
  427.     return (FALSE);
  428.  
  429.     oldlen = 0;            /* use savlin instead */
  430.  
  431.     if ((oldlex != VSAVE && !app) || cnt == 0)
  432.       {             /* if new save, cnt == 0 and not appending */
  433.     slastl=0;
  434.     savlin=0;        /* haven't saved anything */
  435.     savlen=0;
  436.     nxtsav=mxbuff;    /* start saving at end */
  437.     if (cnt == 0)
  438.       {
  439.         return (TRUE);
  440.       }
  441.       }
  442.  
  443.     if (oldlex != VSAPPEND && app)    /* need to reset count for append */
  444.     savlen=0;
  445.  
  446.     lend=min(curlin+cnt-1 ,nxtlin-1);
  447.     for (l=curlin; l <= lend ; ++l)
  448.       {
  449.     if (nxtsav-nxtchr < ALMOSTOUT)    /* make space if need and can */
  450.         if (!gbgcol() || (nxtsav-nxtchr) < ALMOSTOUT)
  451.           {
  452.         tverrb("No save room ");
  453.         return (FALSE);
  454.           }
  455.  
  456.     from = *(lines+l)+1;        /* first character of the line */
  457.     do
  458.       {
  459.         *(buff+nxtsav--) = *(buff+from++);
  460.       }
  461.     while (*(buff+from-1)!=ENDLINE);
  462.     ++savlin;        /* keep track of the length */
  463.     ++savlen;        /* savlen for rmvlst */
  464.     if (curlin==nxtlin-1)    /* don't save last line twice! */
  465.       {
  466.         slastl=1;
  467.         break;
  468.       }
  469.     dwnlin(1);    /* move to next line on screen for + only */
  470.       }
  471.     return (TRUE);
  472.   }
  473.  
  474. /* =============================>>> SEARCH <<<============================= */
  475.   search(lexcnt,iarg)
  476.   int lexcnt,iarg;
  477.   { /* search - search down in buffer for a patter */
  478.  
  479. #define SEARCHEND (-30)
  480.     SLOW char chr,c0,c1,c2;
  481.     static int slines;
  482.     SLOW int oldx,oldy,oldlin;
  483.     SLOW int change, searchv, lininc, newln, fold_wild;
  484.     SLOW int l,lbeg,is;
  485.     SLOW BUFFINDEX ib, bbeg, oldpos, nbbeg;
  486.     FAST int i;
  487.  
  488.     SLOW int how_match, set_len;    /* how wild card matching happens */
  489.     char *cp, *s_getset();
  490.     SLOW int w_len,inset,extra_len;        /* length of match */
  491.  
  492.     static int lastsb = 0;
  493.  
  494.     lininc = (lexcnt >= 0 ) ? 1 : (-1);
  495.     searchv = FALSE;
  496.     newln = FALSE;        /* haven't rubbed out 2nd line */
  497.  
  498.     oldpos = curchr;        /* need to remember for -f */
  499.     oldx = tvx ; oldy = tvy ; oldlin = curlin;
  500.  
  501.     ins_mode = TRUE;        /* so ttymode can echo right */
  502.  
  503.     if (! iarg)
  504.     goto l100;        /* get arg form search buffer */
  505.  
  506.     tvmsg("Find?",FALSE);
  507.  
  508.     if (! grptch(&chr))
  509.     goto l9000;
  510.  
  511.     slines=1;            /* only one line so far */
  512.     for (i = 0; chr != ESC && i < 100; ++i)    /* read in the pattern */
  513.       {
  514.     if (chr == delkey && rptcnt[rptuse] <= 0) /* edit interactive input */
  515.       {
  516.         --i;        /* adjust i for for loop ++i */
  517.         if (i >= 0)        /* wipe out chars on screen */
  518.           {
  519.         if (sbuff[i] == 0)    /* newline */
  520.           {
  521.              --slines; tvcout(CR); newln = TRUE;
  522. #ifdef USELF
  523.             tvcout(LF);
  524. #endif
  525.           }
  526.         else
  527.           {
  528.             if (newln)
  529.               {
  530.             tvcout('\\');
  531.             ctrlch(sbuff[i]);
  532.               }
  533.             else
  534.               {
  535.             tvcout(BACKSPACE);
  536.             tvcout(' ');
  537.             tvcout(BACKSPACE);
  538.             if (sbuff[i] < ' ' && sbuff[i] != 27)
  539.               {
  540.                 tvcout(BACKSPACE);
  541.                 tvcout(' ');
  542.                 tvcout(BACKSPACE);
  543.               }
  544.               }
  545.           }
  546.         --i;        /* wipe the character */
  547.           }
  548.         gkbd(&chr);        /* get new char */
  549.         continue;
  550.       }
  551.     sbuff[i]=chr;        /* stuff it away */
  552.     if (chr == LF)
  553.       {
  554. #ifdef USELF
  555.         tvcout(chr);    /*$$$ to ignore lfs in cr/lf systems */
  556. #endif
  557.       }
  558.     else if (chr == CR)
  559.       {
  560.         if (rptcnt[rptuse] <= 0)
  561.         tvcout(chr);
  562. #ifdef USELF
  563.         tvcout(LF);        /*$$$ when needed */
  564. #endif
  565.         ++slines;
  566.         sbuff[i]=0;    /* end of a line */
  567.       }
  568.     else
  569.         ctrlch(chr);    /* echo character, handline control chars */
  570.  
  571. /*# fetch the next character */
  572.     if (! grptch(&chr))
  573.         goto l9000;
  574.       }
  575.  
  576.     tvcout('$');    /* echo the escape */
  577.     tvxy(oldx,oldy);    /* return to old location */
  578.  
  579.     if (i>0)            /* we got a new pattern */
  580.       {
  581.     lastsb=i-1;        /* last valid character */
  582.     sbuff[i] = 0;        /* make sure an EOS */
  583.       }
  584.     fixend();
  585.  
  586. l100:
  587.     extra_len = 0;
  588.     if (lininc < 0)
  589.     endlin();
  590.     bbeg = curchr;        /* start from current character first time */
  591.     c0 = sbuff[0];        /* initial char of pattern */
  592.     if (!xcases)            /* get initial character of pattern */
  593.     c0 = (c0 >= 'A' && c0 <= 'Z') ? c0+' ' : c0;
  594.  
  595.     for (l = curlin ; l < nxtlin && l ; l += lininc)  /* l is same as l != 0 */
  596.       {
  597.     if ( !c0 )        /* !c0 same as c0 == 0 */
  598.       {
  599.         if (lastsb == 0)    /* matching cr only? */
  600.           {
  601.         dwnlin(1);    /* go down one line */
  602.         newscr();    /* screen needs updating */
  603.         goto l8000;
  604.           }
  605.         else
  606.           {
  607.         for (ib = bbeg; *(buff+ib); ++ib)
  608.             ;
  609.         goto l1000;
  610.           }
  611.       }
  612.  
  613. l900:
  614.     if (c0 < ' ')    /* save time, check if might be w.c. once */
  615.       {
  616.         ib = bbeg;
  617.         if (*(buff+ib))
  618.         goto l1000;
  619.       }
  620.  
  621.     for (ib=bbeg; *(buff+ib); ++ib)    /* search current line */
  622.       {
  623.         c2 = *(buff+ib);    /* next char of buffer */
  624.         if (!xcases)
  625.         c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2;
  626.     
  627.         if (c2 != c0)
  628.         continue;        /* first characters don't match */
  629.         else if (lastsb == 0)
  630.           {         /* one character pattern */
  631.         curchr = ib+1;
  632.         curlin = l;
  633.         goto l5000;    /* successful match */
  634.           }
  635.         else
  636.           {
  637.         if ((c1 = sbuff[1]) < ' ')    /* possible wild? */
  638.             goto l1000;
  639.         c2 = *(buff+ib+1);
  640.         if (! xcases)    /* fold to lower case */
  641.           {
  642.             c1 = (c1 >= 'A' && c1 <= 'Z') ? c1+' ' : c1;
  643.             c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2; /* clower */
  644.           }
  645.         if ( c1 != c2 )
  646.             continue;    /* first two don't match */
  647.         else
  648.             goto l1000;    /* first two match, so possibility */
  649.           }
  650.       }
  651.  
  652. /*    # fall thru => no match on this line */
  653. l950:
  654.     bbeg = *(lines+l+lininc)+1;    /* next beginning character */
  655.     continue;            /* go check next line */
  656.                     
  657. l1000:                /* we have two characters matching! */
  658.     nbbeg = ib;        /* beginning of possible match in buff */
  659.     lbeg = l;         /* current line we are searching */
  660.     how_match = 1;        /* assume exact match */
  661.     for (is = -1 ; ++is <= lastsb ; )
  662.       {
  663.         if ((c1 = sbuff[is]) < ' ')        /* possible wild card */
  664.           {
  665.         if (c1 == W_span)
  666.           {
  667.             extra_len--;
  668.             how_match = 2;        /* span match */
  669.             continue;            /* keep scanning search pat */
  670.           }
  671.         else if (c1 == W_skip)        /* skip? */
  672.           {
  673.             extra_len--;
  674.             how_match = 0;        /* skip match */
  675.             continue;            /* keep scanning search pat */
  676.           }
  677.         else if ((cp = s_getset(c1,&set_len,&fold_wild)) == NULL)    /* not wild */
  678.             goto NOT_WILD;        /* continue normally */
  679.          
  680.     /* ok, to here, then have possible wild card match */
  681.     
  682.         w_len = 0;
  683.  
  684.         for ( ; ; )
  685.           {
  686.             chr = *(buff + nbbeg);    /* pick up char */
  687.             if (fold_wild)        /* fold if not user */
  688.             chr = clower(chr);
  689.             if (chr == ENDLINE)        /* break on end of line */
  690.             break;            /* get out */
  691.     
  692.             inset = s_inset(chr,cp,set_len);    /* see if in set */
  693.             if ((how_match > 0 && inset) || (how_match == 0 && !inset))
  694.               {
  695.             nbbeg++;         /* bump to next char */
  696.             ++w_len;
  697.             if (how_match == 1)
  698.                     break;        /* only once on mode 1 */
  699.               }
  700.             else
  701.             break;
  702.           }
  703.  
  704.         if (w_len <= 0)
  705.           {
  706.             ++bbeg;     /* this part of line doesn't match */
  707.             extra_len = 0;
  708.             if (c0 == 0)
  709.             goto l950;
  710.             else
  711.             goto l900;    /* try rest of current line */
  712.           }
  713.  
  714.     /* to here, then exit from wild card match */
  715.         extra_len += w_len - 1;
  716.         how_match = 1;            /* back to 1 again */
  717.         continue;        /* leave cursor on 1st unmatched */
  718.           }
  719.  
  720. NOT_WILD:
  721.         c2 = *(buff+nbbeg);
  722.         if (! xcases)    /* fold to lower case */
  723.           {
  724.         c1 = (c1 >= 'A' && c1 <= 'Z') ? c1+' ' : c1;
  725.         c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2; /* clower */
  726.           }
  727.  
  728.         if ( c1 != c2 )
  729.           {
  730.         extra_len = 0;
  731.         ++bbeg;     /* this part of line doesn't match */
  732.         if (c0 == 0)
  733.             goto l950;
  734.         else
  735.             goto l900;    /* try rest of current line */
  736.           }
  737.  
  738.     /* regular matched sequence */
  739.  
  740.         if (*(buff+nbbeg)==0 && lbeg+1 < nxtlin)
  741.           {
  742.         ++lbeg;
  743.         nbbeg = *(lines+lbeg)+1;    /* point to next character */
  744.           }
  745.         else
  746.         ++nbbeg;
  747.       }
  748.  
  749. /*#  fall through => found the pattern */
  750.     curlin = lbeg;
  751.     curchr = nbbeg;
  752.  
  753. l5000:
  754.     change = curlin-oldlin;    /* compute real line change */
  755.     if ((slines > 1 && iarg) || tvdlin == tvlins || newln)
  756.         newscr();
  757.     else
  758.         update(change);
  759.     goto l8000;
  760.       }
  761.     curchr = oldpos;        /* reset things */
  762.     tvxy(oldx, oldy);
  763.     if (slines > 1 && iarg)
  764.     newscr();        /* patch up screen */
  765.     pat_buff[0] = 0;
  766.     tverrb("Not found ");    /* announce failure a little */
  767.     goto l9000;
  768.  
  769. l8000:                /* success return */
  770.     oldlen = lastsb+1+extra_len;        /* remember the length */
  771.     save_pat();        /* save the find pattern */
  772.     savlen = (-1);            /* haven't saved lines */
  773.     searchv = TRUE;
  774.  
  775. l9000:
  776.     ins_mode = FALSE;
  777.     return (searchv);
  778.   }
  779.  
  780. /* =============================>>> S_GETSET <<<============================= */
  781.   char *s_getset(wildchr,set_len,fold)
  782.   char wildchr;        /* wild card character */
  783.   int *set_len, *fold;        /* length of set, fold flag */
  784.   {
  785.     static char sets[] =        /* possible sets */
  786.       {
  787.     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  788.     'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  789.     'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
  790.     '4', '5', '6', '7', '8', '9', '.', ',', '?', '!',
  791.     '[', ']', '{', '}', '(', ')', '<', '>', '\'','"',
  792.     '+', '-', '/', '*', '=', '@', '#', '$', '%', '^',
  793.     '&', '_', '~', '`', '|', '\\', ' ', 9, ';', ':', 0
  794.       };
  795.  
  796.     struct wild_set
  797.       {
  798.     char wch;
  799.     int s_start, s_len;
  800.       };
  801.  
  802.     static struct wild_set wild_cards[] =
  803.       {
  804.     { W_letter,  0, 26 },    /* ^L is a letter, starts at 0, 26 long */
  805.     { W_digit, 26, 10 },    /* ^D is digit, starts at 26, 10 long */
  806.     { W_alpha,  0, 36 },    /* ^A is alpha numeric, start at 0, 36 long */
  807.     { W_punc, 36,  4 },    /* ^P is punctuation, at 36, 4 long */
  808.     { W_anything,  0, 70 },    /* ^X is any thing, whole set */
  809.     { W_others, 36, 34 },    /* ^O is non-alphanum, start at 36, 32 long */
  810.     { 0 ,  0,  0 }    /* end of set */
  811.       };
  812.  
  813.     SLOW int i;
  814.     
  815.     *fold = FALSE;        /* assume won't fold */
  816.     if (!use_wild)
  817.     return NULL;        /* not there if not using! */
  818.  
  819.     for (i = 0 ; wild_cards[i].wch ; ++i)    /* scan list */
  820.       {
  821.     if (wildchr == wild_cards[i].wch)    /* found the one we want */
  822.       {
  823.         *set_len = wild_cards[i].s_len;
  824.         *fold = TRUE;
  825.         return (&sets[ wild_cards[i].s_start ]);
  826.       }
  827.       }
  828.     if (wildchr == W_user)
  829.       {
  830.     *set_len = strlen(user_set);
  831.     return user_set;
  832.       }
  833.     else
  834.         return NULL;
  835.  
  836.   }
  837.   
  838. /* =============================>>> S_inset <<<============================= */
  839.   s_inset(c2,cp,set_len)
  840.   char c2, *cp;
  841.   int set_len;
  842.   {
  843.     FAST int i;
  844.  
  845.     for (i = 0 ; i < set_len ; ++i)
  846.         if (c2 == *(cp+i))
  847.             return TRUE;
  848.     return FALSE;
  849.   }
  850.   
  851. /* =============================>>> SETPAR <<<============================= */
  852.   setpar(val)
  853.   int val;
  854.   { /* setpar - reset varoius parameters
  855.         syntax for setpar is [val]:<let>, where [val] is the new value
  856.         of the parameter, : is the setpar command, and <let> is the
  857.         letter of the parameter to set. */
  858.  
  859.     static char chr;
  860.  
  861.     if (! grptch(&chr))
  862.     return;
  863.     chr = clower(chr);
  864.  
  865.     switch (chr)
  866.       {
  867.        case 'a':        /* set auto indent */
  868.          autoin = val > 0;
  869.         break;
  870.  
  871.        case 'e':        /* expand tabs */
  872.          tabspc = max(val,0);
  873.         verify(1);        /* need to redisplay */
  874.         break;
  875.  
  876.     case 'd':        /* display line */
  877.         if (val < 1 || val > tvlins)
  878.         tverrb("Bad par val");
  879.         else
  880.           {
  881.         dsplin=val;
  882.         verify(1);
  883.           }
  884.         break;
  885.  
  886.        case 'f':        /* set find mode */
  887.         xcases = val <= 0;
  888.         break;
  889.  
  890.     case 'm':        /* match wild cards */
  891.         use_wild = val;
  892.         break;
  893.  
  894.     case 'o':
  895.         if (rdonly)
  896.           {
  897.         tverrb("Can't :o, R/O");
  898.         break;
  899.           }
  900.         tvclr();
  901.         ask("New output file name: ",dest_file,FNAMESIZE);
  902.         if (*dest_file)
  903.           {
  904.         expand_name(dest_file);    /* expand output name as needed */
  905.         rdonly = FALSE;
  906.           }
  907.         verify(1);
  908.         break;
  909.  
  910.     case 's':        /* scroll lines */
  911.         if (val < 0 || val > dsplin-1)
  912.         tverrb("Bad par val");
  913.         else
  914.         scroll=val;
  915.         break;
  916.  
  917.     case 't':        /* tty mode */
  918.         tvclr();
  919.         ttymode = val;
  920.         ttynext = 1000;
  921.         verify(1);
  922.         break;
  923.  
  924.     case 'r':        /* change repeat buffer in use */
  925.         if (val < 1 || val > REPEATBUFS)
  926.         tverrb("Bad par val");
  927.         else
  928.         rptuse=val-1;    /* adjust for 0 index int */
  929.         break;
  930.  
  931.     case 'u':
  932.         tvclr();
  933.         ask("Enter user wild card set: ",user_set,39);
  934.         verify(1);
  935.         break;
  936.  
  937.     case 'v':        /* virtual window size */
  938.         if (val < 3 || val > tvhardlines)
  939.         tverrb("Bad par val");
  940.         else
  941.           {
  942.         tvlins = val;            /* set to new display line */
  943.         ddline = (tvlins / 2) + 1;    /* fix home line */
  944.         setdscrl();            /* set scroll value */
  945.         dsplin = ddline;        /* reset these */
  946.         scroll = dscrl;
  947.         verify(1);            /* update the screen */
  948.           }
  949.         break;
  950.  
  951.     case 'w':        /* change wrap width */
  952.         wraplm=val;
  953.         break;
  954.  
  955.     default:
  956.         tverrb("Bad par name");
  957.       }
  958.   }
  959.  
  960. /* =============================>>> SNEXT  <<<============================= */
  961.   snext(lexcnt,iarg)
  962.   int lexcnt,iarg;
  963.   { /* snext - find a text pattern across page boundaries */
  964.  
  965.     SLOW int ihow,pagout;
  966.  
  967.     if (lexcnt < 0)
  968.       {
  969.     tverrb("Search fails");
  970.     return (FALSE);
  971.       }
  972.     
  973.     ihow=iarg;            /* make a local copy */
  974.     pagout=FALSE;
  975.     for(;;)
  976.       {
  977.     if (! search(lexcnt,ihow))
  978.       {
  979.         wtpage(1);        /* write out current page */
  980.         ihow=FALSE;        /* don't reread search pattern */
  981.         pagout=TRUE;
  982.         if (! rdpage())
  983.           {
  984.         tvclr();    /* no more text */
  985.         tverrb("Search fails");
  986.         return (FALSE);
  987.           }
  988.       }
  989.     else            /* found it */
  990.       {
  991.         if (pagout)
  992.         newscr();
  993.         return (TRUE);
  994.       }
  995.       }
  996.   }
  997.  
  998. /* =============================>>> STORE_RPT <<<============================= */
  999.   store_rpt(dummy)
  1000.   int dummy;
  1001.   {    /* start at current cursor position, insert into repeat buffer
  1002.        identified until find >$$ or exceed size limit, deleting as it goes */
  1003.  
  1004.     SLOW char chr;
  1005.     SLOW int saved, i, val;
  1006.  
  1007.     beglin();        /* start by moving to beginning of current line */
  1008.  
  1009.     if ((chr = *(buff+curchr)) != '#')    /* get current char, which must be # */
  1010.       {
  1011.     tverrb("Not a valid rpt buff");
  1012.     return (FALSE);    
  1013.       }
  1014.     val = *(buff+curchr+1)-'0';        /* pick up buffer number */
  1015.  
  1016.     if (!chk_rpt_nr(val))
  1017.         return FALSE;
  1018.  
  1019.     delnxt(4);                /* delete the #n:< */
  1020.  
  1021.     --val;        /* change to relative */
  1022.  
  1023.     saved = 0;                /* no previous chars */
  1024.     for (i = 0 ;  ; ++i)
  1025.       {
  1026.     chr = *(buff+curchr);        /* get the character */
  1027.  
  1028.     if (chr == ESC && i > 1 && rptbuf[val][i-1] == ESC &&
  1029.         rptbuf[val][i-2] == SLOOPEND)
  1030.       {
  1031.         rptbuf[val][i-1] = 0;    /* set to 0 */
  1032.         lstrpt[val] = i - 2;
  1033.         nxtrpt[val] = 0;
  1034.         delnxt(2);            /* delete the 27 and following CR */
  1035.         return TRUE;
  1036.       }
  1037.     if (++saved > 99)
  1038.       {
  1039.         tverrb("Only 100 chars in rpt");
  1040.         return FALSE;
  1041.       }
  1042.     if (chr == ENDLINE)
  1043.         chr = CR;
  1044.     rptbuf[val][i] = chr;            /* save the char */
  1045.     delnxt(1);            /* and delete it */
  1046.       }
  1047.  
  1048.   }
  1049.  
  1050. /* =============================>>> SVKLIN <<<============================= */
  1051.   svklin(lin)
  1052.   int lin;
  1053.   { /* svklin - save one line that will be killed */
  1054.  
  1055.     SLOW BUFFINDEX from,to;
  1056.  
  1057.     to=0;
  1058.     for (from= *(lines+lin)+1; *(buff+from)!=ENDLINE; ++from)
  1059.       {
  1060.     unkbuf[to]= *(buff+from);    /* put it in unkill buffer */
  1061.     to = min(130,to+1);
  1062.       }
  1063.     unkbuf[to]=0;
  1064.   }
  1065.  
  1066. /* =============================>>> TOPPAG <<<============================= */
  1067.   toppag()
  1068.   { /* toppag - move cursor to top of the page */
  1069.  
  1070.     curlin=1;
  1071.     curchr = *(lines+1)+1;        /* first char of buffer */
  1072.     newscr();
  1073.   }
  1074.  
  1075. /* =============================>>> TVIDEFS <<<============================= */
  1076.   tvidefs()
  1077.   { /* initialize these AFTER opening, defaults set by -c */
  1078.  
  1079.     dsplin=ddline;
  1080.     scroll=dscrl;
  1081.     xcases=dxcase;
  1082.   }
  1083.  
  1084. /* =============================>>> TVINIT <<<============================= */
  1085.   tvinit()
  1086.   { /* perform initializations needed for tv edit */
  1087.  
  1088.     FAST BUFFINDEX i;
  1089.     FAST char *chrp;
  1090.     SLOW char *lim;
  1091.     char *malloc();
  1092.  
  1093. #ifdef MSDOS
  1094.     BUFFINDEX coreleft();        /* !!! cii-86 dependent */
  1095. #endif
  1096.  
  1097. /*    This is a time eater if a big buffer -- if your loader inits
  1098.     mem to some known value, it might be possible to change GARBAGE
  1099.     to that value (be sure no other conflicts, like EOS == 0)     */
  1100.  
  1101. /* try for maximum size buffer */
  1102.  
  1103. #ifndef GEMDOS
  1104.     if ((lines = (BUFFINDEX *) malloc((MAXLINE+1)*sizeof(BUFFINDEX)))
  1105.        == NULL)        /* line pointer array */
  1106.     exit(1);
  1107. #else
  1108. if ((lines=(BUFFINDEX *)malloc((unsigned int)((MAXLINE+1)*sizeof(BUFFINDEX))) )
  1109.        == NULL)        /* line pointer array */
  1110.     exit(1);
  1111. #endif
  1112.  
  1113. #ifdef UNIX
  1114.     for (mxbuff=MAXBUFF ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000)
  1115.     ;            /* text buffer pointer */
  1116. #endif
  1117. #ifdef CPM
  1118.     for (mxbuff=MAXBUFF ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000)
  1119.     ;            /* text buffer pointer */
  1120. #endif
  1121. #ifdef GEMDOS
  1122.     for (mxbuff = 60000L ; (buff = malloc((unsigned int) (mxbuff+2)))==NULL
  1123.       ; mxbuff -= 1000L)
  1124.     ;            /* text buffer pointer */
  1125. #endif
  1126. #ifdef MSDOS            /* *** Cii-86 C compiler dependent! */
  1127.  
  1128.     /* cii-86 requires you to manually leave some memory left over
  1129.        for the I/O routines to use.  Sigh. */
  1130.  
  1131.     if ((mxbuff = (coreleft() - 4000) ) > MAXBUFF)
  1132.     mxbuff = MAXBUFF;
  1133.     for ( ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000)
  1134.     ;            /* text buffer pointer */
  1135. #endif
  1136.  
  1137.     mxline = MAXLINE;
  1138.  
  1139.     lim = buff + mxbuff;
  1140.     for (chrp = buff ; chrp <= lim ; *chrp++ = GARBAGE )
  1141.     ;    /* mark as all garbage */
  1142.  
  1143.     curlin =            /* init some stuff */
  1144.     oldlen =
  1145.     curchr = 0;
  1146.  
  1147.     xoutcm = leftmg = nxtlin = nxtchr = tvdlin = 1;
  1148.     *(buff+mxbuff)=0;        /* needs to be null for save buffer */
  1149.     nxtsav=mxbuff;        /* point to end of the buffer */
  1150.  
  1151.     pat_buff[0] = 0;        /* null pattern buffer */
  1152.  
  1153.  
  1154.     savlin = savlen = (-1);
  1155.     for (i = 0 ; i < REPEATBUFS ; ++i)
  1156.       {              /* fix repeat buffers to initial state */
  1157.     rptcnt[i]= nxtrpt[i] = lstrpt[i] = rptbuf[i][1] = 0;
  1158.     rptbuf[i][0]=SLOOPEND;
  1159.       }
  1160.     rptuse=0;            /* start with first repeat buff */
  1161.     bakflg = FALSE;
  1162.     ineof =
  1163.     echof = TRUE;
  1164.   }
  1165.  
  1166. /* =============================>>> TVERR  <<<============================= */
  1167.   tverr(str)
  1168.   char str[];
  1169.   { /* tverr -    display an error message on the last line of the screen
  1170.                always writes on screen, returns to old position */
  1171.  
  1172.     SLOW int oldx,oldy,oldxot,oldech;
  1173.  
  1174.     waserr = TRUE;
  1175.     oldx=tvx ; oldy=tvy ; oldxot=xoutcm ; oldech=echof;
  1176.  
  1177.     ttynext = 1000;        /* force new read */
  1178.  
  1179.     echof = TRUE;            /* always echo! */
  1180.     tvmsg(str,TRUE);         /* print the message part */
  1181.     tvxy(oldx,oldy);
  1182.     xoutcm=oldxot;
  1183.     echof=oldech;        /* restore to what it was */
  1184.   }
  1185.  
  1186. /* =============================>>> TVERRB <<<============================= */
  1187.   tverrb(str)
  1188.   char str[];
  1189.   { /* tverrb - display an error message on the last line of the screen
  1190.               always writes on screen, returns to old position */
  1191.  
  1192.     sendcs(cerrbg);
  1193.     tverr(str);
  1194.     sendcs(cerred);
  1195.   }
  1196.  
  1197. /* =============================>>> TVHDLN <<<============================= */
  1198.   tvhdln()
  1199.   { /* tvhdln - home to display line */
  1200.  
  1201.     SLOW int xf;
  1202.     xf = findx();
  1203.     tvxy(xf,tvdlin);
  1204.   }
  1205.  
  1206. /* =============================>>> TVMSG  <<<============================= */
  1207.   tvmsg(str,intty)
  1208.   char str[];
  1209.   int intty;
  1210.   { /* tvmsg - display a message on the last line of the screen */
  1211.  
  1212.     FAST int i;
  1213.     SLOW int oldtty;
  1214.  
  1215.     tvxy(1,tvhardlines);
  1216.     tvelin();
  1217.     
  1218.     oldtty = ttymode;
  1219.     if (ttymode && intty)
  1220.       {
  1221.     ttymode = FALSE;
  1222.     prompt(">");
  1223.       }
  1224.  
  1225.     for (i=0; str[i]; ctrlch(str[i++]))
  1226.     ;
  1227.  
  1228.     if (oldtty)        /* end with < if was ttymode */
  1229.     remark("<");
  1230.  
  1231.     ttymode = oldtty;
  1232.   }
  1233.  
  1234. /* =============================>>> TVTYLN <<<============================= */
  1235.   tvtyln(chrptr)
  1236.   BUFFINDEX chrptr;
  1237.   { /* tvtyln - type a line on the screen without cr/lf */
  1238.  
  1239. #ifdef ULBD
  1240.     FAST BUFFINDEX i;
  1241.  
  1242.     if (cundlb[0] || cboldb[0])    /* check for underline/bold */
  1243.       {
  1244.     for (i = *(lines+curlin)+1 ; *(buff+i)!=ENDLINE ; ++i)
  1245.         if (*(buff+i)==TOGUNDERLINE || *(buff+i)==TOGBOLD)
  1246.           {
  1247.         tvxy(1,tvy);
  1248.         xoutcm=1;
  1249.         tvplin(*(lines+curlin)+1);
  1250.         return;
  1251.           }
  1252.       }
  1253. #endif
  1254.     xoutcm=tvx;
  1255.     tvplin(chrptr);
  1256.   }
  1257.  
  1258. /* =============================>>> UNKILL <<<============================= */
  1259.   int unkill()
  1260.   { /* unkill the single last line killed */
  1261.  
  1262.     SLOW char chrval;
  1263.     FAST int i;
  1264.  
  1265.     for (i=0; unkbuf[i]; ++i)
  1266.       {
  1267.     chrval=unkbuf[i];
  1268.     if (! ins_chr(chrval))    /* unkill slowly by using insert */
  1269.       {
  1270.         return (FALSE);
  1271.       }
  1272.       }
  1273.     return (ins_chr(CR));
  1274.   }
  1275.  
  1276. /* =============================>>> UPDATE <<<============================= */
  1277.   update(change)
  1278.   int change;
  1279.   { /* update - update the screen when line position has changed
  1280.         will not be used if any alterations have been made */
  1281.  
  1282.     SLOW int abschg,bscrol;
  1283.  
  1284.     if (! echof)
  1285.     return;
  1286.     abschg =  change;
  1287.  
  1288.     bscrol = (ctopb[0]==0) ? 0 : scroll;
  1289.  
  1290.     if (change < 0)            /* have to scroll screen down */
  1291.       {
  1292.     abschg = (-change);
  1293.     if (tvdlin-abschg < 1)
  1294.         newscr();
  1295.     else if (curlin < tvdlin)    /* won't fit exactly */
  1296.       {
  1297.         if (tvdlin >= dsplin-scroll && abschg!=1)
  1298.           {
  1299.         tvclr();        /* clear the screen */
  1300.         tvtype(1,tvlins);    /* type out a screen */
  1301.           }
  1302.         tvdlin=curlin;
  1303.       }
  1304.     else if (tvdlin-abschg >= dsplin-scroll)
  1305.         tvdlin -= abschg;
  1306.     else
  1307.       {
  1308.         if (tvdlin > dsplin-scroll)
  1309.           {             /* moving up from below display line */
  1310.         abschg=dsplin-scroll-(tvdlin-abschg);
  1311.         tvdlin=dsplin-scroll;    /* update */
  1312.           }
  1313.         if (ctopb[0]==0)        /* can't do reverse linefeeds */
  1314.         newscr();        /* no choice, redraw screen */
  1315.         else
  1316.           {
  1317.         tvtopb(abschg);        /* make blank lines at top */
  1318.         tvtype(curlin-tvdlin+1,abschg);    /* fill in */
  1319.           }
  1320.       }
  1321.       }
  1322.     else if (change > 0)        /* have to scroll screen up */
  1323.     if ((tvdlin+change>tvlins && tvdlin<dsplin+bscrol) || change>=tvlins)
  1324.         newscr();
  1325.     else if (tvdlin < dsplin+bscrol || nxtlin-1 <= tvlins)
  1326.         if (tvdlin+change > dsplin+bscrol && nxtlin-1 > tvlins)
  1327.         newscr();
  1328.         else
  1329.         tvdlin += change;
  1330.     else if (nxtlin-curlin<=tvlins-tvdlin)    /* on bottom part */
  1331.       {
  1332.         if (tvdlin<=dsplin+bscrol && abschg!=1)
  1333.           {
  1334.         tvclr();        /* rewrite whole screen */
  1335.         tvtype(nxtlin-tvlins,tvlins);
  1336.           }
  1337.         tvdlin=min(tvlins,nxtlin-1)-(nxtlin-curlin)+1;
  1338.       }
  1339.     else
  1340.       {
  1341.         tvbotb(abschg);        /* make room */
  1342.         tvxy(1,tvlins-abschg+1);    /* home to right line */
  1343.         tvtype(curlin+tvlins-tvdlin-abschg+1,abschg);  /* fix up screen */
  1344.         if (tvdlin < dsplin+bscrol)
  1345.         tvdlin=dsplin;
  1346.       }
  1347.     tvhdln();
  1348.   }
  1349.  
  1350. /* =============================>>> WORDR  <<<============================= */
  1351.   wordr(cnt)
  1352.   int cnt;
  1353.   {  /* wordr - move cursor over words */
  1354.  
  1355.     SLOW int lim,words,incr,lenmov;
  1356.  
  1357.     lenmov=0;
  1358.     if (cnt<0)
  1359.       {
  1360.     incr = (-1);        /* change */
  1361.     lim = (-cnt);
  1362.       }
  1363.     else if (cnt == 0)
  1364.       {
  1365.     incr = -1;
  1366.     lim = 0;
  1367.       }
  1368.     else 
  1369.       {
  1370.     incr = 1;
  1371.     lim = cnt;
  1372.       }
  1373.  
  1374.     for (words=1; words<=lim; ++words)
  1375.       {
  1376.     if ((*(buff+curchr)==ENDLINE && incr>0) ||
  1377.         (*(buff+curchr-1)==BEGLINE && incr<0) )
  1378.       {
  1379.         if (curlin+incr==nxtlin || curlin+incr<1)
  1380.         break;        /* at a buffer limit, so quit */
  1381.         dwnlin(incr);    /* move up or down */
  1382.         lenmov += incr;
  1383.         if (cnt<0)
  1384.         endlin();
  1385.         continue;        /* move to next word */
  1386.       }
  1387.  
  1388. /* ok, first, skip over word characters */
  1389.     while (wrdchr(*(buff+curchr)))
  1390.       {
  1391.         if (*(buff+curchr-1)==BEGLINE && incr<=0)
  1392.         goto l100;
  1393.         else
  1394.           {
  1395.         curchr += incr;
  1396.         lenmov += incr;
  1397.           }
  1398.       }
  1399.  
  1400. /* now skip over remaining non word chars */
  1401.     while (! wrdchr(*(buff+curchr)))
  1402.        {
  1403.         if ((*(buff+curchr)==0 && incr>0) || (*(buff+curchr-1)==BEGLINE &&
  1404.           incr<0))
  1405.         break;
  1406.         else
  1407.           {
  1408.         curchr += incr;
  1409.         lenmov += incr;
  1410.           }
  1411.       }
  1412. l100: ;
  1413.       }
  1414.  
  1415.     if (incr < 0)        /* move cursor to beginning of word */
  1416.     while (wrdchr(*(buff+curchr-1)))
  1417.       {
  1418.         curchr += incr;
  1419.         lenmov += incr;
  1420.       }
  1421.     tvhdln();
  1422.     oldlen = lenmov ; savlen=(-1) ;
  1423.   }
  1424.  
  1425. /* =============================>>> WRDCHR <<<============================= */
  1426.   int wrdchr(chr)
  1427.   char chr;
  1428.   { /* wrdchr - determine if a character is a "word" type character */
  1429.  
  1430.     if ((chr>='a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') ||
  1431.       (chr >= '0' && chr <= '9'))
  1432.     return (TRUE);
  1433.     else
  1434.      return (FALSE);
  1435.   }
  1436. /* -------------------------------- tvx_2.c ------------------------------- */
  1437.